home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 November / CPNL0711.ISO / boekhoud / finan / BADGER finance v1.0 beta 2.exe / xampplite / phpMyAdmin / libraries / import / csv.php next >
PHP Script  |  2006-04-20  |  11KB  |  281 lines

  1. <?php
  2. /* $Id: csv.php,v 1.8.2.2 2006/04/21 07:54:53 nijel Exp $ */
  3. // vim: expandtab sw=4 ts=4 sts=4:
  4.  
  5. /* CSV import plugin for phpMyAdmin */
  6.  
  7. if ($plugin_param == 'table') {
  8.     if (isset($plugin_list)) {
  9.         $plugin_list['csv'] = array(
  10.             'text' => 'strCSV',
  11.             'extension' => 'csv',
  12.             'options' => array(
  13.                 array('type' => 'bool', 'name' => 'replace', 'text' => 'strReplaceTable'),
  14.                 array('type' => 'bool', 'name' => 'ignore', 'text' => 'strIgnoreDuplicates'),
  15.                 array('type' => 'text', 'name' => 'terminated', 'text' => 'strFieldsTerminatedBy', 'size' => 2, 'len' => 2),
  16.                 array('type' => 'text', 'name' => 'enclosed', 'text' => 'strFieldsEnclosedBy', 'size' => 2, 'len' => 2),
  17.                 array('type' => 'text', 'name' => 'escaped', 'text' => 'strFieldsEscapedBy', 'size' => 2, 'len' => 2),
  18.                 array('type' => 'text', 'name' => 'new_line', 'text' => 'strLinesTerminatedBy', 'size' => 2),
  19.                 array('type' => 'text', 'name' => 'columns', 'text' => 'strColumnNames'),
  20.                 ),
  21.             'options_text' => 'strCSVImportOptions',
  22.             );
  23.     } else {
  24.     /* We do not define function when plugin is just queried for information above */
  25.         $replacements = array(
  26.             '\\n'   => "\n",
  27.             '\\t'   => "\t",
  28.             '\\r'   => "\r",
  29.             );
  30.         $csv_terminated = strtr($csv_terminated, $replacements);
  31.         $csv_enclosed = strtr($csv_enclosed,  $replacements);
  32.         $csv_escaped = strtr($csv_escaped, $replacements);
  33.         $csv_new_line = strtr($csv_new_line, $replacements);
  34.  
  35.         if (strlen($csv_terminated) != 1) {
  36.             $message = sprintf($strInvalidCSVParameter, $strFieldsTerminatedBy);
  37.             $show_error_header = TRUE;
  38.             $error = TRUE;
  39.         } elseif (strlen($csv_enclosed) != 1) {
  40.             $message = sprintf($strInvalidCSVParameter, $strFieldsEnclosedBy);
  41.             $show_error_header = TRUE;
  42.             $error = TRUE;
  43.         } elseif (strlen($csv_escaped) != 1) {
  44.             $message = sprintf($strInvalidCSVParameter, $strFieldsEscapedBy);
  45.             $show_error_header = TRUE;
  46.             $error = TRUE;
  47.         } elseif (strlen($csv_new_line) != 1 && $csv_new_line != 'auto') { 
  48.             $message = sprintf($strInvalidCSVParameter, $strLinesTerminatedBy);
  49.             $show_error_header = TRUE;
  50.             $error = TRUE;
  51.         }
  52.  
  53.         $buffer = '';
  54.         if (isset($csv_replace)) {
  55.             $sql_template = 'REPLACE';
  56.         } else {
  57.             $sql_template = 'INSERT';
  58.             if (isset($csv_ignore)) {
  59.                 $sql_template .= ' IGNORE';
  60.             }
  61.         }
  62.         $sql_template .= ' INTO ' . PMA_backquote($table);
  63.         
  64.         $tmp_fields = PMA_DBI_get_fields($db, $table);
  65.         
  66.         if (empty($csv_columns)) {
  67.             $fields = $tmp_fields;
  68.         } else {
  69.             $sql_template .= ' (';
  70.             $fields = array();
  71.             $tmp   = split(',( ?)', $csv_columns);
  72.             foreach ($tmp as $key => $val) {
  73.                 if (count($fields) > 0) {
  74.                     $sql_template .= ', ';
  75.                 }
  76.                 $val = trim($val);
  77.                 $found = FALSE;
  78.                 foreach ($tmp_fields as $id => $field) {
  79.                     if ($field['Field'] == $val) {
  80.                         $found = TRUE;
  81.                         break;
  82.                     }
  83.                 }
  84.                 if (!$found) {
  85.                     $message = sprintf($strInvalidColumn, $val);
  86.                     $show_error_header = TRUE;
  87.                     $error = TRUE;
  88.                     break;
  89.                 }
  90.                 $fields[] = $field;
  91.                 $sql_template .= PMA_backquote($val);
  92.             }
  93.             $sql_template .= ') ';
  94.         }
  95.  
  96.         $required_fields = count($fields);
  97.  
  98.         $sql_template .= ' VALUES (';
  99.  
  100.         // Defaults for parser
  101.         $i = 0;
  102.         $len = 0;
  103.         $line = 1;
  104.         $lasti = -1;
  105.         $values = array();
  106.         $csv_finish = FALSE;
  107.  
  108.         while (!($finished && $i >= $len) && !$error && !$timeout_passed) {
  109.             $data = PMA_importGetNextChunk();
  110.             if ($data === FALSE) {
  111.                 // subtract data we didn't handle yet and stop processing
  112.                 $offset -= strlen($buffer);
  113.                 break;
  114.             } elseif ($data === TRUE) {
  115.                 // Handle rest of buffer
  116.             } else {
  117.                 // Append new data to buffer
  118.                 $buffer .= $data;
  119.                 // Do not parse string when we're not at the end and don't have new line inside
  120.                 if (($csv_new_line == 'auto' && strpos($buffer, "\r") === FALSE && strpos($buffer, "\n") === FALSE)
  121.                     || ($csv_new_line != 'auto' && strpos($buffer, $csv_new_line) === FALSE)) {
  122.                     continue;
  123.                 }
  124.             }
  125.  
  126.             // Current length of our buffer
  127.             $len = strlen($buffer);
  128.             // Currently parsed char
  129.             $ch = $buffer[$i];
  130.             while ($i < $len) {
  131.                 // Deadlock protection
  132.                 if ($lasti == $i && $lastlen == $len) {
  133.                     $message = sprintf($strInvalidCSVFormat, $line);
  134.                     $show_error_header = TRUE;
  135.                     $error = TRUE;
  136.                     break;
  137.                 }
  138.                 $lasti = $i;
  139.                 $lastlen = $len;
  140.  
  141.                 // This can happen with auto EOL and \r at the end of buffer
  142.                 if (!$csv_finish) {
  143.                     // Grab empty field
  144.                     if ($ch == $csv_terminated) {
  145.                         $values[] = '';
  146.                         if ($i == $len - 1) {
  147.                             break;
  148.                         }
  149.                         $i++;
  150.                         $ch = $buffer[$i];
  151.                         continue;
  152.                     }
  153.  
  154.                     // Grab one field 
  155.                     $fallbacki = $i;
  156.                     if ($ch == $csv_enclosed) {
  157.                         $need_end = TRUE;
  158.                         if ($i == $len - 1) {
  159.                             break;
  160.                         }
  161.                         $i++;
  162.                         $ch = $buffer[$i];
  163.                     } else {
  164.                         $need_end = FALSE;
  165.                     }
  166.                     $fail = FALSE;
  167.                     $value = '';
  168.                     while (($need_end && $ch != $csv_enclosed) || (!$need_end && !($ch == $csv_terminated || $ch == $csv_new_line || ($csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))))) {
  169.                         if ($ch == $csv_escaped) {
  170.                             if ($i == $len - 1) {
  171.                                 $fail = TRUE;
  172.                                 break;
  173.                             }
  174.                             $i++;
  175.                             $ch = $buffer[$i];
  176.                         }
  177.                         $value .= $ch;
  178.                         if ($i == $len - 1) {
  179.                             if (!$finished) {
  180.                                 $fail = TRUE;
  181.                             }
  182.                             break;
  183.                         }
  184.                         $i++;
  185.                         $ch = $buffer[$i];
  186.                     }
  187.                     if ($fail) {
  188.                         $i = $fallbacki;
  189.                         $ch = $buffer[$i];
  190.                         break;
  191.                     }
  192.                     // Need to strip trailing enclosing char?
  193.                     if ($need_end && $ch == $csv_enclosed) {
  194.                         if ($finished && $i == $len - 1) {
  195.                             $ch = NULL;
  196.                         } elseif ($i == $len - 1) {
  197.                             $i = $fallbacki;
  198.                             $ch = $buffer[$i];
  199.                             break;
  200.                         } else {
  201.                             $i++;
  202.                             $ch = $buffer[$i];
  203.                         }
  204.                     }
  205.                     // Are we at the end?
  206.                     if ($ch == $csv_new_line || ($csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n")) || ($finished && $i == $len - 1)) {
  207.                         $csv_finish = TRUE;
  208.                     }
  209.                     // Go to next char
  210.                     if ($ch == $csv_terminated) {
  211.                         if ($i == $len - 1) {
  212.                             $i = $fallbacki;
  213.                             $ch = $buffer[$i];
  214.                             break;
  215.                         }
  216.                         $i++;
  217.                         $ch = $buffer[$i];
  218.                     }
  219.                     // If everything went okay, store value
  220.                     $values[] = $value;
  221.                 }
  222.  
  223.                 // End of line
  224.                 if ($csv_finish || $ch == $csv_new_line || ($csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n"))) {
  225.                     if ($csv_new_line == 'auto' && $ch == "\r") { // Handle "\r\n"
  226.                         if ($i >= ($len - 2) && !$finished) {
  227.                             break; // We need more data to decide new line
  228.                         }
  229.                         if ($buffer[$i + 1] == "\n") {
  230.                             $i++;
  231.                         }
  232.                     }
  233.                     // We didn't parse value till the end of line, so there was empty one
  234.                     if (!$csv_finish) {
  235.                         $values[] = '';
  236.                     }
  237.                     // Do we have correct count of values?
  238.                     if (count($values) != $required_fields) {
  239.                         $message = sprintf($strInvalidCSVFieldCount, $line);
  240.                         $show_error_header = TRUE;
  241.                         $error = TRUE;
  242.                         break;
  243.                     }
  244.                     
  245.                     $first = TRUE;
  246.                     $sql = $sql_template;
  247.                     foreach ($values as $key => $val) {
  248.                         if (!$first) {
  249.                             $sql .= ', ';
  250.                         }
  251.                         $sql .= '\'' . addslashes($val) . '\'';
  252.                         $first = FALSE;
  253.                     }
  254.                     $sql .= ')';
  255.  
  256.                     // FIXME: maybe we could add original line to verbose SQL in comment
  257.                     PMA_importRunQuery($sql, $sql);
  258.                     $line++;
  259.                     $csv_finish = FALSE;
  260.                     $values = array();
  261.                     $buffer = substr($buffer, $i + 1);
  262.                     $len = strlen($buffer);
  263.                     $i = 0;
  264.                     $lasti = -1;
  265.                     $ch = $buffer[0];
  266.                 }
  267.             } // End of parser loop
  268.         } // End of import loop
  269.  
  270.         // Commit any possible data in buffers
  271.         PMA_importRunQuery();
  272.         
  273.         if (count($values) != 0 && !$error) {
  274.             $message = sprintf($strInvalidCSVFormat, $line);
  275.             $show_error_header = TRUE;
  276.             $error = TRUE;
  277.         }
  278.     }
  279. }
  280. ?>
  281.